#ifndef _USER_H_
#define _USER_H_
#include "flv_main.h"
#include "http.h"
class user : public http
{
public :
    oal_int32           socket_id;//拉流流用户的socket
    oal_int32           user_id;//拉流用户的id ,mysql
    oal_int32           private_id;//私有id
    oal_int32           puser_id;//推流用户的实体 ,mysql 
    oal_uint8           recv_buff[USER_REV_BUFF_LEN];//接收buf
    oal_uint32          buf_len;
    oal_int32           push_user_id;//推流用户id,mysql
    oal_bool            is_new;//是否新连接上用户
    unordered_map<string,string>  post_map;
    oal_void user_clear() //每次使用对象前先clear
    {
        http_clear();
        socket_id = -1;
        user_id   = -1;
        private_id = -1;
        puser_id  = -1;
        buf_len   = 0;
        push_user_id = -1;
        is_new = true;
        data_addr = recv_buff;
        post_map.clear();
    }
    oal_uint32 parse_one_xml(unordered_map<string,string> &data_map,oal_uint8 *data ,oal_uint32 datalen)
    {
	    oal_uint32 proc_len = 0;
	    string key;
	    string value;
	    oal_int8 *temp =( oal_int8 *) data;
	    oal_int8 *str = temp;
	    if(*temp == '\r'&& *(temp + 1) == '\n')
	    {
		    return 2;
	    }
	    if(*temp == '\n')
	    {
		    return 1;
	    }
	    oal_uint32 str_len = 0;
	    oal_bool   exit_normal = false;
	    while(str_len <= datalen)
	    {
		    if(*str == '=')
		    {
			    exit_normal = true;
			    break;
		    }
		    str_len ++;
		    str ++;
	    }
	    if(!exit_normal)
	    {
		    return str_len;
	    }
	    proc_len += str_len;
	    key.append(temp,str_len);
	    temp = str + 1;
	    str++;
	    proc_len ++;
	    if(proc_len >= datalen)
	    {
		    return proc_len;
	    }
	    str_len = 0; 
	    while(proc_len <= datalen)
	    {
		    if(*str == '&')
		    {
			    value.append(temp,str_len);
			    data_map.insert(pair<string,string>(key,value));
			    printf("post 0  key [%s] value [%s]\n",key.c_str(),value.c_str());
			    return proc_len + 1;//+1 跳过&
		    }
		    str_len ++;
		    proc_len ++;
		    str ++;
	    }
	    value.append(temp,str_len - 1);
	    printf("post 1  key [%s] value [%s]\n",key.c_str(),value.c_str());
	    data_map.insert(pair<string,string>(key,value));
	    return proc_len ;
    }
    oal_bool parse_xml(unordered_map<string,string> &data_map,oal_uint8 *data ,oal_uint32 data_len)
    {
	    oal_uint8 *temp_data = data;
	    oal_uint32  proc_len = 0;
	    while(1)
	    {
		    oal_uint32 temp_len = 0;
		    temp_len = parse_one_xml(data_map,temp_data,data_len - proc_len);
		    proc_len += temp_len;
		    temp_data += temp_len;
		    if(proc_len >= data_len)
		    {
			    break;
		    }
	    }
	    printf("data [%s] proc_len is [%u] datalen [%u]\n",data,proc_len,data_len);
	    return true;
    }
    void find_pusher()
    {
		//test
		puser_id = 1;
    }
    oal_int8  read()
    {
        //http post请求内容在消息主体中
         //读完w
		printf("user read in!!,socket_id [%d]\n",socket_id);
        oal_int32 ret;
        //oal_int32 read_len = 0;
        oal_int32 total_len = 0;
        //user_clear();
        while(total_len < USER_REV_BUFF_LEN)
        {
            ret = recv(socket_id,recv_buff + total_len, USER_REV_BUFF_LEN - total_len ,0);
			printf("user recv len [%d]\n",ret);
            if (ret == 0)//返回0表示连接已关闭
			{
				printf("user connect close!!!\n");
				break;
			}
			else if (ret < 0)
			{
				if (errno == EAGAIN || errno == EWOULDBLOCK)//表示连接没有数据可读，EAGAIN意思是resource unvaluiable
				{
					break;
				}
				else if(EINTR == errno)//表明recv被中断打断，需要重新读
				{
					continue;
				}
				else
				{
					printf("user something wrong happen, errno is [%d]!!\n",errno);
					sleep(10);
					return -1;
				}
			}
			total_len += ret;
            //data_read = recv(temp_fd, http_con[index].read_buff + read_index, BUFFER_SIZE - read_index, 0);
        }
        read_limit_index = total_len;
        if(parse_content() == REQUEST_OK && has_data_enrty == true)
        {
            parse_xml(post_map , data_addr + check_index ,read_limit_index - check_index);
        }
        find_pusher();
		printf("user read out!!\n");
        return 1;
    }
    void write_error()
    {

    }
};
#endif